use r::fred::interfaces::{FunctionInterface, SetsInterface};

use super::{CID, K, LUA};

#[derive(Debug, Clone)]
pub struct Api {
  pub threshold: u64,        // 调用次数
  pub threshold_amount: u64, // 调用次数对应的金额
  pub kid: u64,
}

impl Api {
  pub async fn can_pay(&self, uid: u64) -> anyhow::Result<bool> {
    let uid_bin = intbin::u64_bin(uid);
    Ok(r::R.sismember(K::PAY_ON, &uid_bin[..]).await?)
  }

  pub fn cost(&self, rid: u64, uid: u64, n: u32) -> anyhow::Result<()> {
    // 如果开放这个接口,应该要检查这个uid是否隶属于当前host

    let kid = self.kid;
    let threshold = self.threshold;
    let threshold_amount = self.threshold_amount;

    trt::bg(async move {
      let uid_bin = &intbin::u64_bin(uid)[..];
      let ts = sts::sec();
      let key = [K::PAY_N, &intbin::u64_bin(kid)].concat();
      let cost: Option<u64> = r::R
        .fcall(
          LUA::PAY_N,
          &[&key[..]],
          (uid_bin, n as i64, threshold as i64),
        )
        .await?;
      if let Some(cost) = cost {
        let remain = m::payBillNew!(
          CID::API as _,
          kid,
          rid,
          uid,
          -((threshold_amount * cost) as i64),
          ts
        );
        if remain <= 0 {
          r::R.srem(K::PAY_ON, uid_bin).await?;
        }
      }
      Ok::<_, anyhow::Error>(())
    });
    Ok(())
  }
}
